#include "board.h"
#include<QPainter>
#include<QMouseEvent>

Board::Board(QWidget *parent) : QWidget(parent)
{
   for(int i=0;i<32;i++){
    _s[i].init(i);
   }
   _selectid=-1;
   _bRedTurn=true;
}
Board::~Board(){

}

/*
void Board::drawInitPosition(QPainter &p, int row, int col)
{
    QPoint pt = center(row, col);
    QPoint off = QPoint(_r/6, _r/6);
    int len = _r/3;

    QPoint ptStart;
    QPoint ptEnd;

    if(col != 0)
    {

        ptStart = QPoint(pt.x() - off.x(), pt.y() - off.y());
        ptEnd = ptStart + QPoint(-len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, -len);
        p.drawLine(ptStart, ptEnd);


        ptStart = QPoint(pt.x() - off.x(), pt.y() + off.y());
        ptEnd = ptStart + QPoint(-len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, +len);
        p.drawLine(ptStart, ptEnd);
    }

    if(col != 8)
    {

        ptStart = QPoint(pt.x() + off.x(), pt.y() + off.y());
        ptEnd = ptStart + QPoint(+len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, +len);
        p.drawLine(ptStart, ptEnd);


        ptStart = QPoint(pt.x() + off.x(), pt.y() - off.y());
        ptEnd = ptStart + QPoint(+len, 0);
        p.drawLine(ptStart, ptEnd);
        ptEnd = ptStart + QPoint(0, -len);
        p.drawLine(ptStart, ptEnd);
    }
}

void Board::drawqizi(QPainter &p, int id)
{
    if(isDead(id)) return;

    QColor color;
    if(red(id)) color = Qt::red;
    else color = Qt::black;

    p.setPen(QPen(QBrush(color), 2));

    if(id == _selectid) p.setBrush(Qt::gray);
    else p.setBrush(Qt::yellow);

    p.drawEllipse(cell(id));

    p.setFont(QFont("system", _r*1.2, 700));
    p.drawText(cell(id), name(id), QTextOption(Qt::AlignCenter));
}

QPoint Board::topLeft(int row, int col)
{
    return center(row, col) - QPoint(_r, _r);
}

QPoint Board::topLeft(int id)
{
    return center(id) - QPoint(_r, _r);
}

QRect Board::cell(int row, int col)
{
    return QRect(topLeft(row, col), QSize(_r*2-1, _r*2-1));
}

QRect Board::cell(int id)
{
    return QRect(topLeft(id), QSize(_r*2-1, _r*2-1));
}

*/



void Board::paintEvent(QPaintEvent *){

    //设置棋盘区域的背景颜色和大小
     QPalette palette;

    // 设置棋盘成了米黄
    QLinearGradient linearGradient(0, 0, 400, 400);
    linearGradient.setColorAt(0.0, QColor(216, 180, 80));
    linearGradient.setColorAt(0.2, QColor(216, 160, 72));
    linearGradient.setColorAt(1.0, QColor(216, 156, 72));
    palette.setBrush(QPalette::Background,  QBrush(linearGradient));
    setPalette(palette);
    setAutoFillBackground(true);
    setMinimumSize(600, 660);


    QPainter painter(this);
    QPen pen(Qt::SolidLine);
    int d=40;
    _r=d/2;
    //画10条横线
    for(int i=1;i<=10;i++){
        painter.drawLine(QPoint(d,i*d),QPoint(9*d,i*d));
    }
    //画9条竖线
    for(int i=1;i<=9;i++){
        if(i==1||i==9){
            painter.drawLine(QPoint(i*d,d),QPoint(i*d,10*d));
        }
        else{
            painter.drawLine(QPoint(i*d,d),QPoint(i*d,5*d));
            painter.drawLine(QPoint(i*d,6*d),QPoint(i*d,10*d));
        }
    }
    //画九宫格
    painter.drawLine(QPoint(4*d,1*d),QPoint(6*d,3*d));
    painter.drawLine(QPoint(6*d,1*d),QPoint(4*d,3*d));
    painter.drawLine(QPoint(4*d,8*d),QPoint(6*d,10*d));
    painter.drawLine(QPoint(6*d,8*d),QPoint(4*d,10*d));

    //绘制棋子
    for(int i=0;i<32;i++){
        drawqizi(painter,i);
    }

    //画楚河汉界
    QPainter p(this);
    QPointF point(d*3, d*5.7);
    p.setFont(QFont("Arial", 15));
    p.drawText(point, "楚河      汉界");

    //绘制直角
    pen.setWidth(2);
    p.setPen(pen);

        for(int j=2; j>0; j--)
        {
            for(int i=1; i<5; i++)  /* 兵的井字格 */
            {
                QPoint points1[3] = {
                    QPoint(d*(2*i-1)+5,d*(10-j*3)-15),
                    QPoint(d*(2*i-1)+5,d*(10-j*3)-5),
                    QPoint(d*(2*i-1)+15,d*(10-j*3)-5),
                };
                p.drawPolyline(points1, 3);

                QPoint points2[3] = {
                    QPoint(d*(2*i+1)-15,d*(10-j*3)-5),
                    QPoint(d*(2*i+1)-5,d*(10-j*3)-5),
                    QPoint(d*(2*i+1)-5,d*(10-j*3)-15),
                };
                p.drawPolyline(points2, 3);

                QPoint points3[3] = {
                    QPoint(d*(2*i-1)+5,d*(10-j*3)+15),
                    QPoint(d*(2*i-1)+5,d*(10-j*3)+5),
                    QPoint(d*(2*i-1)+15,d*(10-j*3)+5),
                };
                p.drawPolyline(points3, 3);

                QPoint points4[3] = {
                    QPoint(d*(2*i+1)-15,d*(10-j*3)+5),
                    QPoint(d*(2*i+1)-5,d*(10-j*3)+5),
                    QPoint(d*(2*i+1)-5,d*(10-j*3)+15),
                };
                p.drawPolyline(points4, 3);


                if(i < 3)   /* 炮的井字格 */
                {
                    QPoint points5[3] = {
                        QPoint(d*pow(2, 2*i-1)-15,d*(pow(j+1,2)-1)-5),
                        QPoint(d*pow(2, 2*i-1)-5,d*(pow(j+1,2)-1)-5),
                        QPoint(d*pow(2, 2*i-1)-5,d*(pow(j+1,2)-1)-15),
                    };
                    p.drawPolyline(points5, 3);

                    QPoint points6[3] = {
                        QPoint(d*pow(2, 2*i-1)+15,d*(pow(j+1,2)-1)-5),
                        QPoint(d*pow(2, 2*i-1)+5,d*(pow(j+1,2)-1)-5),
                        QPoint(d*pow(2, 2*i-1)+5,d*(pow(j+1,2)-1)-15),
                    };
                    p.drawPolyline(points6, 3);

                    QPoint points7[3] = {
                        QPoint(d*pow(2, 2*i-1)-15, d*(pow(j+1,2)-1)+5),
                        QPoint(d*pow(2, 2*i-1)-5, d*(pow(j+1,2)-1)+5),
                        QPoint(d*pow(2, 2*i-1)-5, d*(pow(j+1,2)-1)+15),
                    };
                    p.drawPolyline(points7, 3);

                    QPoint points8[3] = {
                        QPoint(d*pow(2, 2*i-1)+15,d*(pow(j+1,2)-1)+5),
                        QPoint(d*pow(2, 2*i-1)+5,d*(pow(j+1,2)-1)+5),
                        QPoint(d*pow(2, 2*i-1)+5,d*(pow(j+1,2)-1)+15),
                    };
                    p.drawPolyline(points8, 3);
                }

            }

        }
}


bool Board::canselect(int id){
    return _bRedTurn==_s[id]._red;
}

void Board::tryselectqizi(int id){
    if(id==-1){
        return;
    }
    if(!canselect(id)){
        return;
    }
    _selectid=id;
    update();
}

bool Board::isDead(int id){
    if(id==-1){
        return true;
    }
    return _s[id]._dead;
}

bool Board::samecolor(int id1, int id2){
    if(id1==1||id2==-1){
        return false;
    }
    return red(id1)==red(id2);
}

void Board::trymoveqizi(int killid, int row, int col){
    if(killid!=-1&&samecolor(killid,_selectid)){
        tryselectqizi(killid);
        return;
    }
    bool ret=canMove(_selectid,killid,row,col);
    if(ret){
        moveqizi(_selectid,killid,row,col);
        _selectid=-1;
        update();
    }
}

bool Board::red(int id){
    return _s[id]._red;
}

QPoint Board::center(int row,int col){
    QPoint ret;
    ret.rx()=(col+1)*_r*2;
    ret.ry()=(row+1)*_r*2;
    return ret;
}

QPoint Board::center(int id){
    return center(_s[id]._row,_s[id]._col);
}

void Board::drawqizi(QPainter &painter,int id){
    if(_s[id]._dead){
        return;
    }
    QPoint c=center(id);
    QRect rect=QRect(c.x()-_r,c.y()-_r,_r*2,_r*2);

    if(id==_selectid){
        painter.setBrush(QBrush(Qt::gray));
    }
    else{
        painter.setBrush(QBrush(Qt::yellow));
    }

    painter.setPen(Qt::black);
    painter.drawEllipse(center(id),_r,_r);
    if(_s[id]._red){
    painter.setPen(Qt::red);
    }
    painter.setFont(QFont("system",_r,700));
    painter.drawText(rect,_s[id].getText(),QTextOption(Qt::AlignCenter));
}

bool Board::getRowCol(QPoint pt, int &row, int &col){
    for(row=0;row<=9;row++){
        for(col=0;col<=8;col++){
            QPoint c=center(row,col);
            int dx=c.x()-pt.x();
            int dy=c.y()-pt.y();
            int dist=dx*dx+dy*dy;
            if(dist<_r*_r){
                return true;
            }
        }
    }
    return false;
}

int Board::getqiziCountAtline(int row1, int col1, int row2, int col2){
    int ret=0;
    if(row1!=row2&&col1!=col2){
        return -1;
    }
    if(row1==row2&&col1==col2){
        return -1;
    }
    if(row1==row2){
        int min=col1<col2?col1:col2;
        int max=col1<col2?col2:col1;
        for(int col=min+1;col<max;col++){
            if(getqiziId(row1,col)!=-1){
                ret++;
            }
        }
    }
    else{
        int min=row1<row2?row1:row2;
        int max=row1<row2?row2:row1;
        for(int row=min+1;row<max;row++){
            if(getqiziId(row,col1)!=-1){
                ret++;
            }
        }
    }
    return ret;
}


bool Board::canMoveJIANG(int moveid,int row,int col,int ){
    //目标位置在九宫内
    //移动一个格子
    if(_s[moveid]._red){
        if(row>2){
            return false;
        }
    }
    else{
        if(row<7){
            return false;
        }
    }
    if(col<3){
        return false;
    }
    if(col>5){
        return false;
    }
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*10+abs(dc);
    if(d==1||d==10){
        return true;
    }
    return false;
}

bool Board::canMoveSHI(int moveid,int row,int col,int ){
   if(_s[moveid]._red){
        if(row>2){
            return false;
        }
    }
    else{
        if(row<7){
            return false;
        }
    }
    if(col<3){
        return false;
    }
    if(col>5){
        return false;
    }
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*10+abs(dc);
    if(d==11){
        return true;
    }
    return false;
}

bool Board::canMoveXIANG(int moveid,int row,int col,int){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*10+abs(dc);
    if(d!=22){
        return false;
    }
    int rEye=(_s[moveid]._row+row)/2;
    int cEye=(_s[moveid]._col+col)/2;
    if(getqiziId(rEye,cEye)!=-1){
        return false;
    }
   if(isBottomSide(moveid)){
        if(row<4){
            return false;
        }
    }
    else{
        if(row>5){
            return false;
        }
    }
    return true;
}

bool Board::canMoveCHE(int moveid,int row,int col,int){
    int ret=getqiziCountAtline(_s[moveid]._row,_s[moveid]._col,row,col);
    if(ret==0){
        return true;
    }
    return false;
}

bool Board::canMoveMA(int moveid,int row,int col,int){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*10+abs(dc);
    if(d!=12&&d!=21){
        return false;
    }
    if(d==12){
        if(getqiziId(_s[moveid]._row,(_s[moveid]._col+col)/2)!=-1){
            return false;
        }
    }
    else{
        if(getqiziId((_s[moveid]._row+row)/2,_s[moveid]._col)!=-1){
            return false;
        }
    }
    return true;
}

bool Board::canMovePAO(int moveid,int row,int col,int killid){
    int ret=getqiziCountAtline(row,col,_s[moveid]._row,_s[moveid]._col);
    if(killid!=-1){
        if(ret==1){
            return true;
        }
    }
    else{
        if(ret==0){
            return true;
        }
    }
    return false;
}

bool Board::canMoveBING(int moveid,int row,int col,int){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*10+abs(dc);
    if(d!=1&&d!=10){
        return false;
    }
    if(isBottomSide(moveid)){
        if(row>_s[moveid]._row){
            return false;
        }
        if(_s[moveid]._row>=5&&row==_s[moveid]._row){
            return false;
        }
    }
    else{
        if(row<_s[moveid]._row){
            return false;
        }
        if(_s[moveid]._row<=4&&row==_s[moveid]._row){
            return false;
        }
    }
    return true;
}

bool Board::isBottomSide(int id){
    return _bSide==_s[id]._red;
}

int Board::getqiziId(int row, int col){
    for(int i=0;i<32;i++){
        if(_s[i]._row==row&&_s[i]._col==col&&!isDead(i)){
            return i;
        }
    }
    return -1;
}

bool Board::canMove(int moveid, int row, int col, int killid){
    //moveid和killid颜色相同
    if(samecolor(moveid,killid)){
        return false;
    }
    switch(_s[moveid]._type){
    case qizi::JIANG:
        return canMoveJIANG(moveid,row,col,killid);
        break;
    case qizi::SHI:
        return canMoveSHI(moveid,row,col,killid);
        break;
    case qizi::XIANG:
         return canMoveXIANG(moveid,row,col,killid);
        break;
    case qizi::CHE:
         return canMoveCHE(moveid,row,col,killid);
        break;
    case qizi::MA:
         return canMoveMA(moveid,row,col,killid);
        break;
    case qizi::PAO:
         return canMovePAO(moveid,row,col,killid);
        break;
    case qizi::BING:
         return canMoveBING(moveid,row,col,killid);
        break;
    }

    return false;
}

bool Board::getClickRowCol(QPoint pt, int &row, int &col)
{
    for(row=0; row<=9; ++row)
    {
        for(col=0; col<=8; ++col)
        {
            QPoint distance = center(row, col) - pt;
            if(distance.x() * distance.x() + distance.y() * distance.y() < _r* _r)
                return true;
        }
    }
    return false;
}

void Board::mouseReleaseEvent(QMouseEvent *ev){
    QPoint pt=ev->pos();
    //将pt转化为象棋行列值
    //判断行列值上有无棋子
    int row,col;
    bool bRet=getRowCol(pt,row,col);
    if(bRet==false){//点到棋盘外
        return;
    }
    int i;
    int clickid=-1;
    for(i=0;i<32;i++){
        if(_s[i]._row==row&&_s[i]._col==col&&_s[i]._dead==false){
            break;
        }
    }
    if(i<32){
        clickid=i;

    }
    if(_selectid==-1){
        if(clickid!=-1){
            if(_bRedTurn==_s[clickid]._red){
            _selectid=clickid;
            update();
            }
        }
  }
    else{
       if(canMove(_selectid,row,col,clickid)){
        //走棋子
           _s[_selectid]._row=row;
           _s[_selectid]._col=col;
           if(clickid!=-1){
            _s[clickid]._dead=true;
           }
           _selectid=-1;
           _bRedTurn=!_bRedTurn;
           update();
        }
    }
    update();
}

void Board::reliveqizi(int id)
{
    if(id==-1) return;
    _s[id]._dead = false;
}

void Board::killqizi(int id)
{
    if(id==-1) return;
    _s[id]._dead = true;
}

void Board::moveqizi(int moveid, int row, int col)
{
    _s[moveid]._row = row;
    _s[moveid]._col = col;

    _bRedTurn = !_bRedTurn;
}
//保存棋盘
void Board::saveStep(int moveid, int killid, int row, int col, QVector<Step*>& steps)
{
    Step* step = new Step;
    step->_colFrom = _s[moveid]._col ;
    step->_colTo = col;
    step->_rowFrom = _s[moveid]._row;
    step->_rowTo = row;
    step->_moveid = moveid;
    step->_killid = killid;

    steps.append(step);
}

void Board::moveqizi(int moveid, int killid, int row, int col)
{
    saveStep(moveid, killid, row, col, _steps);

    killqizi(killid);
    moveqizi(moveid, row, col);
}

void Board::click(int id, int row, int col)
{
    if(this->_selectid == -1)
    {
        tryselectqizi(id);
    }
    else
    {
        trymoveqizi(id, row, col);
    }
}

void Board::click(QPoint pt)
{
    int row, col;
    bool bClicked = getClickRowCol(pt, row, col);
    if(!bClicked) return;

    int id = getqiziId(row, col);
    click(id, row, col);
}

void Board::back(Step *step)
{
    reliveqizi(step->_killid);
    moveqizi(step->_moveid, step->_rowFrom, step->_colFrom);
}

void Board::backone()
{
    if(this->_steps.size() == 0) return;

    Step* step = this->_steps.last();
    _steps.removeLast();
    back(step);

    update();
    delete step;
}

void Board::back()
{
    backone();
}

void Board::slotback()
{
    back();
}

